﻿using System;

namespace winS.UnityEditor.ProcessEditor
{
    /// <summary>
    /// 文件变化监视器.
    /// 如果文件在编辑时发生任何变化, 提示用户
    /// </summary>
    public class FileChangeWatcher : IDisposable
    {
        /// <summary>
        /// 用户希望重新加载
        /// </summary>
        public Action onReload;
        /// <summary>
        /// 用户希望放弃当前更改
        /// </summary>
        public Action onDiscard;
        /// <summary>
        /// 当前编辑的文件发生了重命名
        /// </summary>
        public Action<string> onRenamed;

        /// <summary>
        /// 是否正在等待用户确认
        /// </summary>
        public bool waitingForUserConfirmation { get; private set; }

        private readonly ProcessEditor processEditor;

        private string pathRelativeProject;

        private FileChangeDialogueBox dialogueBox;

        public FileChangeWatcher(ProcessEditor processEditor)
        {
            this.processEditor = processEditor;
            AssetWatcher.onDeletedAsset += OnFileDeleted;
            AssetWatcher.onRenamedAsset += OnRenamedAsset;
            AssetWatcher.onImportedAsset += OnImportedAsset;
        }

        public void StartWatch(EditorProcessInfo editorProcessInfo)
        {
            pathRelativeProject = editorProcessInfo.pathRelativeProject;
        }
        public void EndWatch()
        {
            pathRelativeProject = null;
        }

        private void OnFileDeleted(string pathRelativeProject)
        {
            if (this.pathRelativeProject != pathRelativeProject) return;
            waitingForUserConfirmation = true;
            OpenDialogueBox($"{pathRelativeProject}\r\n\r\n当前编辑的文件已被删除, 是否放弃编辑?", "放弃当前编辑", () => onDiscard?.Invoke(), "继续当前编辑");
            EndWatch();
        }
        private void OnRenamedAsset(string newPath, string oldPath)
        {
            if (pathRelativeProject != oldPath) return;
            pathRelativeProject = newPath;
            onRenamed?.Invoke(newPath);
        }
        private void OnImportedAsset(string pathRelativeProject)
        {
            if (this.pathRelativeProject != pathRelativeProject) return;
            waitingForUserConfirmation = true;
            OpenDialogueBox($"{pathRelativeProject}\r\n\r\n当前编辑的文件有外部更改, 是否放弃你当前所做的编辑, 并重新加载它?", "放弃当前编辑并重新加载", () => onReload?.Invoke(), "继续当前编辑");
        }

        public void Dispose()
        {
            AssetWatcher.onDeletedAsset -= OnFileDeleted;
            AssetWatcher.onRenamedAsset -= OnRenamedAsset;
            AssetWatcher.onImportedAsset -= OnImportedAsset;
        }

        private void OpenDialogueBox(string content, string yesText, Action yesCallback, string noText)
        {
            if (dialogueBox == null) processEditor.rootVisualElement.Add(dialogueBox = new FileChangeDialogueBox());
            dialogueBox.Show(content, yesText, () =>
            {
                waitingForUserConfirmation = false;
                yesCallback?.Invoke();
            }, noText, () => waitingForUserConfirmation = false);
        }
    }
}